﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tensop.Net.Tcp.Protocol
{
    public class ReceiveProtocolParser : IProtocolService
    {
        public short GetKeys()
        {
           return ProtocolCatcher.MappingKey( 0, (byte)HeaderProtocolType.Receive);
        }

        public byte[] Parse(byte[] data, Client c)
        {
            if ( Validate( data ) )
            {
                var protocol = new HeaderProtocol( HeaderProtocolType.ReceiveCompleted);
                protocol._baseData = data;
                protocol.ContentLength = BitConverter.ToInt32( protocol._baseData, 4 );
                return ProtocolToByte( Execution( protocol, c ) );
            }
            return data;
        }

        public ArraySegment<byte> Parse(ArraySegment<byte> data, Client c)
        {
            if ( Validate( data ) )
            {
                var protocol = new HeaderProtocol( HeaderProtocolType.ReceiveCompleted );
                var d = new byte[data.Count];
                Array.Copy( data.Array, data.Offset, d, 0, data.Count );
                protocol._baseData = d;
                protocol.ContentLength = BitConverter.ToInt32( protocol._baseData, 4 );
                return new ArraySegment<byte>( ProtocolToByte( Execution( protocol, c ) ));
            }
            return data;
        }

        public byte[] Parse(object protocol)
        {
            return ( (HeaderProtocol) protocol ).ToArray();
        }

        bool Validate(ArraySegment<byte> data)
        {
            var d = new byte[data.Count];
            Array.Copy( data.Array, data.Offset, d, 0, data.Count );
            return Validate( d );
        }
        bool Validate(byte[] e)
        {
            if ( e != null && e.Length == 20 )
            {
                var i = BitConverter.ToInt32( e, 4 );
                var l = BitConverter.ToInt64( e, 8 );
                var b = e[0] == 0x12 && e[1] == 0x13 && e[16] == 0x14 &&
                        e[17] == 0x15 && e[18] == 0x16 && e[19] == 0x17;
                return ( i >= 0 && i <= int.MaxValue && ( DateTime.Now - new DateTime( l ) ).TotalMinutes < 3 ) && b;
            }
            return false;
        }

        HeaderProtocol Execution(HeaderProtocol echo,Client c)
        {
            c.ContentLength = echo.ContentLength;
            return new HeaderProtocol( HeaderProtocolType.HeaderReceiveCompleted);
        }
        byte[] ProtocolToByte(HeaderProtocol echo) => echo.ToArray();
    }
}
